/**
 * Copyright 2021 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied。
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup MindSpore
 * @{
 * 
 * @brief 提供MindSpore Lite的模型推理相关接口。
 * 
 * @Syscap SystemCapability.Ai.MindSpore
 * @since 9
 */

/**
 * @file context.h
 * 
 * @brief 提供了Context相关的接口，可以配置运行时信息。
 * 
 * @since 9
 */
#ifndef MINDSPORE_INCLUDE_C_API_CONTEXT_C_H
#define MINDSPORE_INCLUDE_C_API_CONTEXT_C_H

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "mindspore/types.h"

#ifdef __cplusplus
extern "C"
{
#endif
/**
 * @brief Mindspore的上下文信息的指针，该指针会指向Context。
 *
 * @since 9
 */
typedef void *OH_AI_ContextHandle;

/**
 * @brief Mindspore的运行设备信息的指针。
 * 
 * @since 9
 */
typedef void *OH_AI_DeviceInfoHandle;

/**
 * \brief 创建一个上下文的对象。
 *
 * @return 指向上下文信息的{@link OH_AI_ContextHandle}。
 * @since 9
 */
OH_AI_API OH_AI_ContextHandle OH_AI_ContextCreate();

/**
 * \brief 释放上下文对象。
 *
 * \param context 指向{@link OH_AI_ContextHandle}的二级指针，上下文销毁后会对context置为空指针。
 * @since 9
 */
OH_AI_API void OH_AI_ContextDestroy(OH_AI_ContextHandle *context);

/**
 * \brief 设置运行时的线程数量。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}
 * \param thread_num 运行时的线程数量。
 * @since 9
 */
OH_AI_API void OH_AI_ContextSetThreadNum(OH_AI_ContextHandle context, int32_t thread_num);

/**
 * \brief 获取线程数量。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \return 当前的线程数量。
 * @since 9
 */
OH_AI_API int32_t OH_AI_ContextGetThreadNum(const OH_AI_ContextHandle context);

/**
 * \brief 设置运行时线程绑定CPU核心的策略，按照CPU物理核频率分为大、中、小三种类型的核心，并且仅需绑大核或者绑中核，不需要绑小核。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \param mode 绑核策略。一共有三种策略，0为不绑核, 1为大核优先, 2为中核优先。
 * @since 9
 */
OH_AI_API void OH_AI_ContextSetThreadAffinityMode(OH_AI_ContextHandle context, int mode);

/**
 * \brief 获取运行时线程绑定CPU核心的策略。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \return 绑核策略。一共有三种策略，0为不绑核, 1为大核优先, 2为中核优先。
 * @since 9
 */
OH_AI_API int OH_AI_ContextGetThreadAffinityMode(const OH_AI_ContextHandle context);

/**
 * \brief 设置运行时线程绑定CPU核心的列表。
 * 
 * 例如：当core_list=[2,6,8]时，则线程会在CPU的第2,6,8个核心上运行。
 * 如果对于同一个上下文对象，调用了{@link OH_AI_ContextSetThreadAffinityMode}和{@link OH_AI_ContextSetThreadAffinityCoreList}
 * 这两个函数，则仅{@link OH_AI_ContextSetThreadAffinityCoreList}的core_list参数生效，而{@link OH_AI_ContextSetThreadAffinityMode}的 mode参数不生效。
 * 
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \param core_list CPU绑核的列表。
 * \param core_num 核的数量，它就代表{@link core_list}的长度。
 * @since 9
 */
OH_AI_API void OH_AI_ContextSetThreadAffinityCoreList(OH_AI_ContextHandle context, const int32_t *core_list,
                                                        size_t core_num);

/**
 * \brief 获取CPU绑核列表。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \param core_num 该参数是输出参数，表示核的数量。
 * \return CPU绑核列表。
 * @since 9
 */
OH_AI_API const int32_t *OH_AI_ContextGetThreadAffinityCoreList(const OH_AI_ContextHandle context, size_t *core_num);

/**
 * \brief 设置运行时是否支持并行。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \param is_parallel 是否支持并行。true 为支持并行, false 为不支持并行。
 * @since 9
 */
OH_AI_API void OH_AI_ContextSetEnableParallel(OH_AI_ContextHandle context, bool is_parallel);

/**
 * \brief 获取是否支持算子间并行。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \return 是否支持并行。true 为支持并行, false 为不支持并行。
 * @since 9
 */
OH_AI_API bool OH_AI_ContextGetEnableParallel(const OH_AI_ContextHandle context);

/**
 * \brief 添加运行设备信息。
 *
 * \param context 指向上下文信息实例的{@link OH_AI_ContextHandle}。
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * @since 9
 */
OH_AI_API void OH_AI_ContextAddDeviceInfo(OH_AI_ContextHandle context, OH_AI_DeviceInfoHandle device_info);

/**
 * \brief 创建一个设备信息对象。
 *
 * \param device_type 设备类型, 具体见{@link OH_AI_DeviceType}。
 *
 * \return 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * @since 9
 */
OH_AI_API OH_AI_DeviceInfoHandle OH_AI_DeviceInfoCreate(OH_AI_DeviceType device_type);

/**
 * \brief 释放设备信息实例。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * @since 9
 */
OH_AI_API void OH_AI_DeviceInfoDestroy(OH_AI_DeviceInfoHandle *device_info);

/**
 * \brief 设置供应商的名称。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * \param provider 供应商的名称。
 * @since 9
 */
OH_AI_API void OH_AI_DeviceInfoSetProvider(OH_AI_DeviceInfoHandle device_info, const char *provider);

/**
 * \brief 获取生产商的名称。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 *
 * \return 生产商的名称。
 * @since 9
 */
OH_AI_API const char *OH_AI_DeviceInfoGetProvider(const OH_AI_DeviceInfoHandle device_info);

/**
 * \brief 设置生产商设备的名称。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * \param device 生产商设备名称。 例如: CPU。
 * @since 9
 */
OH_AI_API void OH_AI_DeviceInfoSetProviderDevice(OH_AI_DeviceInfoHandle device_info, const char *device);

/**
 * \brief 获取生产商设备的名称。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 *
 * \return 生产商设备的名称。
 * @since 9
 */
OH_AI_API const char *OH_AI_DeviceInfoGetProviderDevice(const OH_AI_DeviceInfoHandle device_info);

/**
 * \brief 获取设备的类型。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * \return 生产商设备类型。
 * @since 9
 */
OH_AI_API OH_AI_DeviceType OH_AI_DeviceInfoGetDeviceType(const OH_AI_DeviceInfoHandle device_info);

/**
 * \brief 设置是否开启float16推理模式，仅CPU/GPU设备可用。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * \param is_fp16 是否开启float16推理模式。
 * @since 9
 */
OH_AI_API void OH_AI_DeviceInfoSetEnableFP16(OH_AI_DeviceInfoHandle device_info, bool is_fp16);

/**
 * \brief 获取是否开启float16推理模式, 仅CPU/GPU设备可用。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * \return 设置是否开启float16推理模式。
 * @since 9
 */
OH_AI_API bool OH_AI_DeviceInfoGetEnableFP16(const OH_AI_DeviceInfoHandle device_info);

/**
 * \brief 设置NPU的频率，仅NPU设备可用。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 * \param frequency 频率类型，取值范围为0-4，默认是3。1表示低功耗，2表示平衡，3表示高性能，4表示超高性能。
 * @since 9
 */
OH_AI_API void OH_AI_DeviceInfoSetFrequency(OH_AI_DeviceInfoHandle device_info, int frequency);

/**
 * \brief 获取NPU的频率类型，仅NPU设备可用。
 *
 * \param device_info 指向设备信息实例的{@link OH_AI_DeviceInfoHandle}。
 *
 * \return NPU的频率类型。取值范围为0-4，1表示低功耗，2表示平衡，3表示高性能，4表示超高性能。
 * @since 9
 */
OH_AI_API int OH_AI_DeviceInfoGetFrequency(const OH_AI_DeviceInfoHandle device_info);

#ifdef __cplusplus
}
#endif

/** @} */
#endif // MINDSPORE_INCLUDE_C_API_CONTEXT_C_H
